﻿#include "CZoomChartView.h"
#include <QtCharts/QChart>
#include <QValueAxis>
#include <QDebug>

CZoomChartView::CZoomChartView(QWidget *parent)
	: QChartView(parent)
	, m_isDragging(false)
	, m_zoomFactor(1.0)
	, m_zoomInProgress(false)
{
	setRubberBand(QChartView::RectangleRubberBand);
	setDragMode(QChartView::ScrollHandDrag);
	setMouseTracking(true);

	m_zoomTimer = new QTimer(this);
	m_zoomTimer->setSingleShot(true);
	connect(m_zoomTimer, &QTimer::timeout, this, &CZoomChartView::completeZoom);
}

CZoomChartView::CZoomChartView(QChart *chart, QWidget *parent)
	: QChartView(chart, parent)
	, m_isDragging(false)
	, m_zoomFactor(1.0)
	, m_zoomInProgress(false)
{
	setRubberBand(QChartView::RectangleRubberBand);
	setDragMode(QChartView::ScrollHandDrag);
	setMouseTracking(true);

	m_zoomTimer = new QTimer(this);
	m_zoomTimer->setSingleShot(true);
	connect(m_zoomTimer, &QTimer::timeout, this, &CZoomChartView::completeZoom);
}

void CZoomChartView::wheelEvent(QWheelEvent *event)
{
	if (chart() == nullptr || m_zoomInProgress)
		return;

	// 计算缩放因子
	qreal zoomFactor = 1.0;
	if (event->angleDelta().y() > 0) {
		zoomFactor = 1.2;  // 放大
	}
	else {
		zoomFactor = 0.8;  // 缩小
	}

	// 获取有效的图表坐标点
	QPointF chartPos = getValidChartPoint(event->pos());

	// 执行缩放
	performZoom(zoomFactor, chartPos);

	m_zoomInProgress = true;
	m_zoomTimer->start(100);

	event->accept();
}

void CZoomChartView::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::RightButton) {
		// 右键重置缩放
		resetZoom();
		event->accept();
		return;
	}

	if (event->button() == Qt::LeftButton) {
		m_isDragging = true;
		m_lastMousePos = event->pos();
		setCursor(Qt::ClosedHandCursor);
		event->accept();
	}
	else {
		QChartView::mousePressEvent(event);
	}
}

void CZoomChartView::mouseMoveEvent(QMouseEvent *event)
{
	if (m_isDragging && (event->buttons() & Qt::LeftButton)) {
		QPoint delta = event->pos() - m_lastMousePos;

		// 平滑滚动
		chart()->scroll(-delta.x() * 1.5, delta.y() * 1.5);

		m_lastMousePos = event->pos();
		event->accept();
	}
	else {
		QChartView::mouseMoveEvent(event);
	}
}

void CZoomChartView::mouseReleaseEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton && m_isDragging) {
		m_isDragging = false;
		setCursor(Qt::ArrowCursor);
		event->accept();
	}
	else {
		QChartView::mouseReleaseEvent(event);
	}
}

void CZoomChartView::mouseDoubleClickEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton) {
		resetZoom();
		event->accept();
	}
	else {
		QChartView::mouseDoubleClickEvent(event);
	}
}

void CZoomChartView::zoomIn()
{
	if (chart()) {
		QPointF center = chart()->plotArea().center();
		performZoom(1.5, center);
	}
}

void CZoomChartView::zoomOut()
{
	if (chart()) {
		QPointF center = chart()->plotArea().center();
		performZoom(0.67, center);
	}
}

void CZoomChartView::resetZoom()
{
	if (chart()) {
		chart()->zoomReset();
	}
}

void CZoomChartView::completeZoom()
{
	m_zoomInProgress = false;
}

void CZoomChartView::performZoom(qreal factor, const QPointF &centerPoint)
{
	if (chart() == nullptr) return;

	// 执行缩放
	chart()->zoom(factor);

	// 调整视图以确保以指定点为中心
	QRectF plotArea = chart()->plotArea();
	if (plotArea.isValid()) {
		QPointF currentCenter = chart()->mapToPosition(centerPoint);
		QPointF expectedCenter = plotArea.center();

		qreal scrollX = currentCenter.x() - expectedCenter.x();
		qreal scrollY = currentCenter.y() - expectedCenter.y();

		chart()->scroll(scrollX, scrollY);
	}
}

QPointF CZoomChartView::getValidChartPoint(const QPoint &pos)
{
	if (!chart()) return QPointF();

	QPointF scenePos = mapToScene(pos);
	QRectF plotArea = chart()->plotArea();

	if (plotArea.contains(scenePos)) {
		return chart()->mapToValue(scenePos);
	}
	else {
		// 如果点在绘图区域外，返回绘图区域中心对应的图表值
		return chart()->mapToValue(plotArea.center());
	}
}